﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;
using System.IO;
using System.Web.UI;

namespace WebComponents.UI.Controls
{
    public class CompressedCss
    {
          /// <summary>
        /// Reading all files with extensions on specific folder 
        /// </summary>
        /// <param name="serverPath"></param>
        /// <param name="extention"></param>
        /// <returns></returns>
        public static string CombineFile(string serverPath, string extention)
        {
            string output = string.Empty;

            foreach (FileInfo fi in GetFiles(serverPath, extention))
            {
                using (StreamReader sr = new StreamReader(fi.FullName))
                    output += sr.ReadToEnd();
            }
            output = CompressFile(output);
            return output;
        }

        public static string CombineFile(string serverPath, string[] files)
        {
            string output = string.Empty;
            if (!serverPath.StartsWith("~/"))
            {
                if (serverPath.StartsWith("/"))
                    serverPath = "~" + serverPath;
                else
                    serverPath = "~/" + serverPath;
            }

            string path = HttpContext.Current.Server.MapPath(serverPath);

            if (!path.EndsWith("/"))
                path = path + "/";

            if (!Directory.Exists(path))
                throw new System.IO.DirectoryNotFoundException();

            foreach (string file in files)
            {
                using (StreamReader sr = new StreamReader(String.Format("{0}{1}", path, file)))
                    output += sr.ReadToEnd();
            }
            output = CompressFile(output);
            return output;
        }

        public static string CombineFile(string serverPath, string extention, string folderPath, string writeToName)
        {
           string output = string.Empty;

            foreach (FileInfo fi in GetFiles(serverPath, extention))
            {
                using (StreamReader sr = new StreamReader(fi.FullName))
                    output += CompressFile(sr.ReadToEnd());
            }


            return WriteToFile(GetPath(folderPath), writeToName, CompressFile(output));
        }

        public static string CombineFile(string serverPath, string[] files, string folderPath, string writeToName)
        {
            return WriteToFile(GetPath(serverPath), writeToName, CombineFile(serverPath, files));
        }

        public static void CombineFile(string serverPath, string[] files, Page page, string linkCssID)
        {
            string css = CombineFile(serverPath, files);
            StringBuilder sb = new StringBuilder();
            string DynamicID = String.Format("CSS{0}", System.Guid.NewGuid().ToString().Replace("-", "").ToUpper());
            sb.Append(String.Format("var {0} = '{1}';", DynamicID, String.Format("{0}", css.Replace("'", string.Empty))));
            sb.Append(String.Format(@"function PageOnLoadCss() {0}var c = document.getElementById('{2}');if (c != null) {0} c.innerHTML = {3}{1}{1}", "{", "}", linkCssID, DynamicID));
            page.ClientScript.RegisterClientScriptBlock(page.GetType(), "RegisterCss", sb.ToString(), true);
        }

        private static string CompressFile(string body)
        {
            body = Regex.Replace(body, "/\\*.+?\\*/", "", RegexOptions.Singleline);
            body = body.Replace("  ", string.Empty);
            body = body.Replace(Environment.NewLine + Environment.NewLine + Environment.NewLine, string.Empty);
            body = body.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
            body = body.Replace(Environment.NewLine, string.Empty);
            //body = body.Replace("\\t", string.Empty);
            body = body.Replace(" {", "{");
            body = body.Replace(" :", ":");
            body = body.Replace(": ", ":");
            body = body.Replace(", ", ",");
            body = body.Replace("; ", ";");
            body = body.Replace(";}", "}");
            body = Regex.Replace(body, "/\\*[^\\*]*\\*+([^/\\*]*\\*+)*/", "$1");
            body = Regex.Replace(body, "(?<=[>])\\s{2,}(?=[<])|(?<=[>])\\s{2,}(?=&nbsp;)|(?<=&ndsp;)\\s{2,}(?=[<])", string.Empty);
            body = body.Replace("\t", string.Empty);
            body = body.Replace("  ", " ");

            return body;
        }

        private static IList<System.IO.FileInfo> GetFiles(string serverPath, string extention)
        {
            IList<FileInfo> files = new List<FileInfo>();

            string[] fileNames = Directory.GetFiles(GetPath(serverPath), "*." + extention, System.IO.SearchOption.AllDirectories);
            foreach (string name in fileNames)
                files.Add(new FileInfo(name));

            return files;
        }
       
        private static string WriteToFile(string folderPath, string writeToName, string writeText)
        {
            StreamWriter fp = default(StreamWriter);
            try
            {
                fp = File.CreateText(String.Format("{0}{1}", folderPath, writeToName));
                fp.WriteLine("/*");
                fp.WriteLine("Using Css/Javascripts Combination Function");
                fp.WriteLine(String.Format("Generated By: {0}", "Ryan Lam"));
                fp.WriteLine(String.Format("Last Generated: {0}", DateTime.Now.ToString()));
                fp.WriteLine("*/");
                fp.WriteLine(writeText);
                fp.Close();
                return "successed!";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        private static string GetPath(string folderPath)
        {
            if (!folderPath.StartsWith("~/"))
            {
                if (folderPath.StartsWith("/"))
                    folderPath = "~" + folderPath;
                else
                    folderPath = "~/" + folderPath;
            }

            string path = HttpContext.Current.Server.MapPath(folderPath);

            if (!path.EndsWith("/"))
                path = path + "/";

            return path;
        }
    }
}
